﻿namespace Webinator
{
    using System;
    using System.Collections.Generic;
    using System.IO;

    /// <summary>
    /// Defines a configuration for an <c>IWebManager</c> instance.
    /// </summary>
    public class Config
    {
        // TODO: Move in the timeouts and implicit waits
        private Dictionary<string, object> _desiredCapabilities;

        private string _logDirectory;

        private TimeSpan _commandTimeout;

        /// <summary>
        /// Initializes a new instance of the <see cref="Config"/> class.
        /// </summary>
        public Config()
        {
            HighlightElements = true;
            HighlightStyle = @"background-color:yellow; border:2px dotted red;";
            UseJavascript = true;
            UseJquery = true;
            LogLevel = AvailableLogLevels.Verbose;
            LogScreenshots = true;
            LogDirectory = string.Format(@"{0}\Logs", AppDomain.CurrentDomain.BaseDirectory);
            LogRealTime = true;
            Framework = AvailableFrameworks.WebDriver;
            Browser = AvailableBrowsers.Firefox;
            NetExportDirectory = string.Format(@"{0}\NetExport", AppDomain.CurrentDomain.BaseDirectory);
        }

        public enum AvailableLogLevels
        {
            None, Errors, Verbose
        }

        public enum AvailableFrameworks
        {
            WebDriver, WatiN, WebDriverRemote
        }

        public enum AvailableBrowsers
        {
            // ReSharper disable InconsistentNaming
            Chrome, Firefox, FirefoxPerformance, FirefoxPlugins, FirefoxSsl, InternetExplorer, Opera, Android, IPhone, IPad, HtmlUnit, HtmlUnitWithJavaScript
            // ReSharper restore InconsistentNaming
        }

        public bool HighlightElements { get; set; }

        public string HighlightStyle { get; set; }

        public bool UseJquery { get; set; }

        public bool UseJavascript { get; set; }

        public bool LogScreenshots { get; set; }

        public AvailableLogLevels LogLevel { get; set; }

        public string LogDirectory
        {
            get
            {
                return _logDirectory;
            }
            
            set
            {
                _logDirectory = value;

                if (!_logDirectory.Contains(":") && !_logDirectory.StartsWith(@"\\"))
                {
                    if (_logDirectory.StartsWith(@"\")) _logDirectory = _logDirectory.Substring(1);
                    _logDirectory = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, _logDirectory);
                }

                if (!Directory.Exists(_logDirectory)) Directory.CreateDirectory(_logDirectory);
            }
        }

        public bool LogRealTime { get; set; }

        public string BaseUrl { get; set; }

        public AvailableBrowsers Browser { get; set; }

        public AvailableFrameworks Framework { get; set; }

        public string NetExportDirectory { get; set; }

        public string SeleniumGridHubUri { get; set; }

        /// <summary>
        /// Gets or sets the desired capabilities.
        /// Valid keys: browserName, platform, version, javascriptEnabled, takesScreenshot, handlesAlerts, cssSelectorsEnabled, proxy, rotatable, acceptSslCerts, nativeEvents
        /// </summary>
        public Dictionary<string, object> DesiredCapabilities
        {
            get
            {
                return _desiredCapabilities ?? (_desiredCapabilities = new Dictionary<string, object>());
            }

            set
            {
                _desiredCapabilities = value;
            }
        }

        /// <summary>
        /// Gets or sets the resource timeout - how long to wait for a resource from Selenium Grid 2 before failing.
        /// Defaults to 5 minutes.
        /// </summary>
        public TimeSpan CommandTimeout
        {
            get
            {
                if (_commandTimeout == default(TimeSpan))
                {
                    _commandTimeout = new TimeSpan(0, 5, 0);
                }

                return _commandTimeout;
            }
            
            set
            {
                _commandTimeout = value;
            }
        }

        public string BrowserLocation { get; set; }

        public string ProfileDirectory { get; set; }
    }
}